{"AccountScreens":null,"AccountTransactionDocumentTypes":null,"AccountTransactionTypes":[{"DefaultSourceAccountName":"Receivables","DefaultTargetAccountName":"Cash","ForeignCurrencyName":null,"Name":"Payment Transaction","SortOrder":0,"SourceAccountTypeName":"Receivable Accounts","TargetAccountTypeName":"Payment Accounts"},{"DefaultSourceAccountName":"CC Fee","DefaultTargetAccountName":"Receivables","ForeignCurrencyName":null,"Name":"Convenience Fee Transaction","SortOrder":130,"SourceAccountTypeName":"Sales Accounts","TargetAccountTypeName":"Receivable Accounts"}],"AccountTypes":[{"DefaultFilterType":0,"Name":"Receivable Accounts","SortOrder":0,"Tags":null,"WorkingRule":0},{"DefaultFilterType":0,"Name":"Payment Accounts","SortOrder":0,"Tags":null,"WorkingRule":0},{"DefaultFilterType":0,"Name":"Sales Accounts","SortOrder":0,"Tags":null,"WorkingRule":0}],"Accounts":[{"AccountTypeName":"Receivable Accounts","ForeignCurrencyName":"NZD","Name":"Receivables"},{"AccountTypeName":"Payment Accounts","ForeignCurrencyName":"NZD","Name":"Cash"},{"AccountTypeName":"Payment Accounts","ForeignCurrencyName":"NZD","Name":"EFTPOS"},{"AccountTypeName":"Sales Accounts","ForeignCurrencyName":null,"Name":"CC Fee"}],"Actions":[{"ActionType":"StartProcess","Name":"ACT-Pay using SMARTPAY","Parameter":"[{\"Key\":\"FileName\",\"Value\":\"C:\\\\SmartPay App\\\\SambaPayment.exe\"},{\"Key\":\"Arguments\",\"Value\":\"[:Arguments]\"},{\"Key\":\"UseShellExecute\",\"Value\":\"True\"},{\"Key\":\"IsHidden\",\"Value\":\"False\"}]","SortOrder":0},{"ActionType":"ExecuteScript","Name":"ACT-Execute Script Clean","Parameter":"[{\"Key\":\"Function\",\"Value\":\"Payment.ClearTransact()\"},{\"Key\":\"Command\",\"Value\":null},{\"Key\":\"Parameters\",\"Value\":null},{\"Key\":\"RunInBackground\",\"Value\":null}]","SortOrder":0},{"ActionType":"ExecuteScript","Name":"ACT-Execute Script Process","Parameter":"[{\"Key\":\"Function\",\"Value\":\"Payment.CheckTransact(130)\"},{\"Key\":\"Command\",\"Value\":null},{\"Key\":\"Parameters\",\"Value\":null},{\"Key\":\"RunInBackground\",\"Value\":null}]","SortOrder":0},{"ActionType":"ExecuteScript","Name":"ACT-Execute Script Process Reset","Parameter":"[{\"Key\":\"Function\",\"Value\":\"Payment.ConfirmTransact()\"},{\"Key\":\"Command\",\"Value\":null},{\"Key\":\"Parameters\",\"Value\":null},{\"Key\":\"RunInBackground\",\"Value\":null}]","SortOrder":0},{"ActionType":"ExecuteAutomationCommand","Name":"ACT-Purchase Process","Parameter":"[{\"Key\":\"AutomationCommandName\",\"Value\":\"ACM-SmartPay Confirm\"},{\"Key\":\"CommandValue\",\"Value\":null},{\"Key\":\"Background\",\"Value\":null},{\"Key\":\"Delay\",\"Value\":null}]","SortOrder":0},{"ActionType":"ExecuteAutomationCommand","Name":"ACT-Refund Process","Parameter":"[{\"Key\":\"AutomationCommandName\",\"Value\":\"ACM-SmartPay Confirm Refund\"},{\"Key\":\"CommandValue\",\"Value\":null},{\"Key\":\"Background\",\"Value\":null},{\"Key\":\"Delay\",\"Value\":null}]","SortOrder":0},{"ActionType":"ExecuteScript","Name":"ACT-Execute Script SmartPay","Parameter":"[{\"Key\":\"Function\",\"Value\":\"[:func]\"},{\"Key\":\"Command\",\"Value\":\"\"},{\"Key\":\"Parameters\",\"Value\":null},{\"Key\":\"RunInBackground\",\"Value\":\"False\"}]","SortOrder":0},{"ActionType":"UpdateTicketService","Name":"ACT-Purchase Update Fee","Parameter":"[{\"Key\":\"CalculationType\",\"Value\":\"Surcharge\"},{\"Key\":\"Amount\",\"Value\":\"[:amount]\"},{\"Key\":\"ResetTicket\",\"Value\":null},{\"Key\":\"RemoveCalculation\",\"Value\":null},{\"Key\":\"RoundAmount\",\"Value\":null}]","SortOrder":0},{"ActionType":"PayTicket","Name":"ACT-Process SmartPay","Parameter":"[{\"Key\":\"PaymentTypeName\",\"Value\":\"EFTPOS\"},{\"Key\":\"TenderedAmount\",\"Value\":\"[:tendered]\"},{\"Key\":\"Description\",\"Value\":null},{\"Key\":\"ExecutePaymentProcessors\",\"Value\":\"False\"}]","SortOrder":0},{"ActionType":"UpdateOrder","Name":"Refund Item Action","Parameter":"[{\"Key\":\"Name\",\"Value\":null},{\"Key\":\"Quantity\",\"Value\":null},{\"Key\":\"Price\",\"Value\":\"[=0-Order.Price]\"},{\"Key\":\"PortionName\",\"Value\":null},{\"Key\":\"PriceTag\",\"Value\":null},{\"Key\":\"IncreaseInventory\",\"Value\":\"True\"},{\"Key\":\"DecreaseInventory\",\"Value\":null},{\"Key\":\"CalculatePrice\",\"Value\":\"True\"},{\"Key\":\"Locked\",\"Value\":null},{\"Key\":\"DisablePortionSelection\",\"Value\":null},{\"Key\":\"TaxTemplate\",\"Value\":\"15%\"},{\"Key\":\"AccountTransactionType\",\"Value\":null},{\"Key\":\"WarehouseName\",\"Value\":null},{\"Key\":\"UpdateAllOrders\",\"Value\":\"\"},{\"Key\":\"RequireSelection\",\"Value\":null}]","SortOrder":0},{"ActionType":"SaveTicket","Name":"Save Ticket","Parameter":"[{\"Key\":\"SuccessCommand\",\"Value\":null},{\"Key\":\"ErrorCommand\",\"Value\":null}]","SortOrder":70},{"ActionType":"ShowMessage","Name":"Show Message","Parameter":"[{\"Key\":\"Message\",\"Value\":\"[:Message]\"}]","SortOrder":0},{"ActionType":"UpdateOrderState","Name":"Update Order Gift State","Parameter":"[{\"Key\":\"StateName\",\"Value\":\"GStatus\"},{\"Key\":\"GroupOrder\",\"Value\":\"1\"},{\"Key\":\"CurrentState\",\"Value\":\"[:Current Status]\"},{\"Key\":\"State\",\"Value\":\"[:Status]\"},{\"Key\":\"StateOrder\",\"Value\":\"1\"},{\"Key\":\"StateValue\",\"Value\":\"[:Value]\"}]","SortOrder":-1},{"ActionType":"ExecuteScript","Name":"ACT-FastPay Prepare TEST","Parameter":"[{\"Key\":\"Function\",\"Value\":\"Payment.PrepareFastPurchase('[:order]')\"},{\"Key\":\"Command\",\"Value\":\"\"},{\"Key\":\"Parameters\",\"Value\":null},{\"Key\":\"RunInBackground\",\"Value\":\"False\"}]","SortOrder":0},{"ActionType":"ExecuteScript","Name":"ACT-FastPay Check TEST","Parameter":"[{\"Key\":\"Function\",\"Value\":\"Payment.CheckFastPurchaseFromStart(130, '[:amount]')\"},{\"Key\":\"Command\",\"Value\":\"\"},{\"Key\":\"Parameters\",\"Value\":null},{\"Key\":\"RunInBackground\",\"Value\":\"False\"}]","SortOrder":0}],"AutoConfigurationTasks":null,"AutomationCommands":[{"AutoRefresh":0,"AutomationCommandMaps":[{"DisplayOnCommandSelector":false,"DisplayOnNavigation":false,"DisplayOnOrders":false,"DisplayOnPayment":false,"DisplayOnTicket":false,"DisplayOnTicketList":false,"DisplayUnderTicket":true,"DisplayUnderTicket2":false,"EnabledStates":"*","VisibleStates":"*"}],"ButtonHeader":"SmartPay","Category":"General","ClearSelection":true,"Color":"#FF1F497D","ConfirmationType":0,"ContentTemplate":null,"ExecuteOnce":true,"FontSize":26,"Image":null,"Name":"ACM-Pay SMARTPAY","NavigationModule":null,"SortOrder":10,"Symbol":null,"TileCacheLifetime":0,"ToggleValues":false,"Values":null},{"AutoRefresh":0,"AutomationCommandMaps":[],"ButtonHeader":null,"Category":null,"ClearSelection":true,"Color":null,"ConfirmationType":0,"ContentTemplate":null,"ExecuteOnce":false,"FontSize":26,"Image":null,"Name":"ACM-SmartPay Confirm","NavigationModule":null,"SortOrder":200,"Symbol":null,"TileCacheLifetime":0,"ToggleValues":false,"Values":null},{"AutoRefresh":0,"AutomationCommandMaps":[{"DisplayOnCommandSelector":false,"DisplayOnNavigation":false,"DisplayOnOrders":true,"DisplayOnPayment":false,"DisplayOnTicket":false,"DisplayOnTicketList":false,"DisplayUnderTicket":false,"DisplayUnderTicket2":false,"EnabledStates":"*","VisibleStates":"*"}],"ButtonHeader":"Refund","Category":null,"ClearSelection":true,"Color":"#FFFFA500","ConfirmationType":0,"ContentTemplate":null,"ExecuteOnce":true,"FontSize":26,"Image":null,"Name":"ACM-Refund Item","NavigationModule":null,"SortOrder":220,"Symbol":null,"TileCacheLifetime":0,"ToggleValues":false,"Values":null},{"AutoRefresh":0,"AutomationCommandMaps":[],"ButtonHeader":null,"Category":null,"ClearSelection":true,"Color":null,"ConfirmationType":0,"ContentTemplate":null,"ExecuteOnce":false,"FontSize":26,"Image":null,"Name":"ACM-SmartPay Confirm Refund","NavigationModule":null,"SortOrder":250,"Symbol":null,"TileCacheLifetime":0,"ToggleValues":false,"Values":null}],"CalculationSelectors":null,"CalculationTypes":[{"AccountTransactionTypeName":"Convenience Fee Transaction","Amount":0.0,"CalculationMethod":2,"DecreaseAmount":false,"IncludeTax":true,"MaxAmount":0.0,"Name":"Surcharge","Rounding":0.0,"SortOrder":10,"ToggleCalculation":true,"UsePlainSum":false}],"ChangePaymentTypes":null,"CustomReports":null,"Departments":null,"EntityScreens":null,"EntityTypes":null,"Numerators":null,"OrderTagGroups":null,"PaymentTypes":[{"AccountName":"EFTPOS","AccountTransactionTypeName":"Payment Transaction","ButtonColor":"#FF1F497D","ButtonHeader":null,"FontSize":26,"Name":"EFTPOS","OrderStateName":null,"OrderStateValue":null,"PaymentTypeMaps":[{"DepartmentId":0,"TerminalId":0,"TicketTypeId":0,"UserRoleId":0}],"ProcessorSettings":"[{\"D\":\"EFTPOS\",\"N\":\"Execute Automation Command\",\"O\":0,\"S\":\"{\\\"CommandName\\\":\\\"ACM-Pay SMARTPAY\\\"}\"}]","SortOrder":20}],"PrintJobs":null,"PrinterTemplates":null,"Printers":null,"ProgramSettingValues":null,"Rules":[{"Actions":[{"ActionName":null,"CustomConstraint":"[=Data.Get(\"SmartPay\")] >0","Name":"ACT-Process SmartPay","ParameterValues":"tendered=[=Data.Get(\"SmartPay\")]","SortOrder":30},{"ActionName":null,"CustomConstraint":"[=Data.Get(\"SmartPay\")] >0","Name":"Show Message","ParameterValues":"Message=Processed Purchase Payment: [=Data.Get(\"SmartPay\")]","SortOrder":50},{"ActionName":null,"CustomConstraint":null,"Name":"ACT-Execute Script SmartPay","ParameterValues":"func=Payment.ClaimFastPurchase('{TICKET ID}')","SortOrder":10},{"ActionName":null,"CustomConstraint":"[=Data.Get(\"SmartPay\")] > 0","Name":"Save Ticket","ParameterValues":"","SortOrder":40},{"ActionName":null,"CustomConstraint":"[=Data.Get(\"SmartPayFee\")] > 0","Name":"ACT-Purchase Update Fee","ParameterValues":"amount=[=Data.Get(\"SmartPayFee\")]","SortOrder":20}],"AppRuleMaps":[{"DepartmentId":0,"TerminalId":0,"TicketTypeId":0,"UserRoleId":0}],"ConstraintMatch":0,"EventName":"AutomationCommandExecuted","Name":"RULE-SmartPay Confirm","RuleConstraints":"[{\"L\":\"AutomationCommandName\",\"N\":\"46AQBIdQE4\",\"O\":\"Equal\",\"R\":\"ACM-SmartPay Confirm\"},{\"L\":\"[=Data.Get(\\\"SmartPay\\\")]\",\"N\":\"Z3jkaesDrx\",\"O\":\"Greater\",\"R\":\"0\"},{\"L\":\"{CALL:Payment.FastPurchaseReady('{TICKET ID}')}\",\"N\":\"FastPayReadyTest\",\"O\":\"Equal\",\"R\":\"1\"}]","SortOrder":0,"Tags":null},{"Actions":[{"ActionName":null,"CustomConstraint":null,"Name":"ACT-Pay using SMARTPAY","ParameterValues":"Arguments=GBPOS-{TICKET ID}-{REMAINING TOTAL}-refund","SortOrder":30},{"ActionName":null,"CustomConstraint":null,"Name":"Save Ticket","ParameterValues":"","SortOrder":10},{"ActionName":null,"CustomConstraint":null,"Name":"ACT-Execute Script Clean","ParameterValues":"","SortOrder":20},{"ActionName":null,"CustomConstraint":null,"Name":"ACT-Execute Script Process","ParameterValues":"","SortOrder":40},{"ActionName":null,"CustomConstraint":null,"Name":"ACT-Execute Script Process Reset","ParameterValues":"","SortOrder":50},{"ActionName":null,"CustomConstraint":null,"Name":"ACT-Refund Process","ParameterValues":"","SortOrder":60}],"AppRuleMaps":[{"DepartmentId":0,"TerminalId":0,"TicketTypeId":0,"UserRoleId":0}],"ConstraintMatch":0,"EventName":"AutomationCommandExecuted","Name":"RULE-Refund Item Rule","RuleConstraints":"[{\"L\":\"AutomationCommandName\",\"N\":\"ThFjoB0CaX\",\"O\":\"Equal\",\"R\":\"ACM-Refund Item\"}]","SortOrder":0,"Tags":null},{"Actions":[{"ActionName":null,"CustomConstraint":null,"Name":"Show Message","ParameterValues":"Message=Processed Refund: [=Data.Get(\"SmartPay\")]","SortOrder":50},{"ActionName":null,"CustomConstraint":null,"Name":"ACT-Execute Script SmartPay","ParameterValues":"func=Payment.GetRefund({TICKET ID})","SortOrder":30},{"ActionName":null,"CustomConstraint":null,"Name":"Save Ticket","ParameterValues":"","SortOrder":40},{"ActionName":null,"CustomConstraint":null,"Name":"Refund Item Action","ParameterValues":"","SortOrder":10},{"ActionName":null,"CustomConstraint":null,"Name":"Update Order Gift State","ParameterValues":"Current Status=`Status=Refund`Value=","SortOrder":20}],"AppRuleMaps":[{"DepartmentId":0,"TerminalId":0,"TicketTypeId":0,"UserRoleId":0}],"ConstraintMatch":0,"EventName":"AutomationCommandExecuted","Name":"RULE-SmartPay Confirm Refund","RuleConstraints":"[{\"L\":\"AutomationCommandName\",\"N\":\"F8Bk6F8lfP\",\"O\":\"Equal\",\"R\":\"ACM-SmartPay Confirm Refund\"},{\"L\":\"{CALL:Payment.GetRefund({TICKET ID})}\",\"N\":\"ygM3qJtWFg\",\"O\":\"Less\",\"R\":\"0\"}]","SortOrder":0,"Tags":null},{"Actions":[{"ActionName":null,"CustomConstraint":"[=Data.Get(\"FastPayReady\")] == 1","Name":"ACT-Pay using SMARTPAY","ParameterValues":"Arguments=[=Data.Get(\"FastPayRequest\")]-{TICKET ID}-[=TN('{REMAINING TOTAL}')]-purchase","SortOrder":20},{"ActionName":null,"CustomConstraint":null,"Name":"ACT-FastPay Prepare TEST","ParameterValues":"order={TICKET ID}","SortOrder":10},{"ActionName":null,"CustomConstraint":"[=Data.Get(\"FastPayReady\")] == 1","Name":"ACT-FastPay Check TEST","ParameterValues":"amount=[=TN('{REMAINING TOTAL}')]","SortOrder":30},{"ActionName":null,"CustomConstraint":null,"Name":"ACT-Purchase Process","ParameterValues":"","SortOrder":50},{"ActionName":null,"Name":"Show Message","CustomConstraint":"[=Data.Get(\"FastPayError\")] != \"\"","ParameterValues":"Message=[=Data.Get(\"FastPayError\")]","SortOrder":90}],"AppRuleMaps":[{"DepartmentId":0,"TerminalId":0,"TicketTypeId":0,"UserRoleId":0}],"ConstraintMatch":0,"EventName":"AutomationCommandExecuted","Name":"RULE-Smartpay Auto Purchase","RuleConstraints":"[{\"L\":\"AutomationCommandName\",\"N\":\"ItajF9U3V0\",\"O\":\"Equal\",\"R\":\"ACM-Pay SMARTPAY\"}]","SortOrder":0,"Tags":null}],"Scripts":[{"Code":"\r\nfunction startTimer () {\r\n    timer.start();\r\n    setTimeout(stopTimer,1000);\r\n}\r\n\r\nfunction stopTimer () {\r\n    timer.stop;\r\n}\r\n\r\nfunction GetVariable()\r\n{\r\n\tData.Set('SmartPay', 'Payment');\r\n\treturn Data.Get('SmartPay');\r\n}\r\n\r\n\r\n\r\nfunction GetPayment()\r\n{\r\n\tvar smartpay = Data.Get('SmartPay');;\r\n\tData.Set('SmartPay', smartpay);\r\n\treturn Data.Get('SmartPay');\r\n}\r\n\r\n\r\n\r\nfunction GetRefund(order)\r\n{\r\n\tvar refund = GetTransact(order);\r\n\t\r\n\tif (refund != 0)\r\n\t{\r\n\t\trefund = 0 - refund; \r\n\t}\r\n\t\r\n\tData.Set('SmartPay', refund);\r\n\t\r\n\treturn Data.Get('SmartPay');\r\n\t\r\n}\r\n\r\nfunction GetTransact(order)\r\n{\r\n\tData.Set('SmartPay', 10);\r\n\t\r\n\tvar i = 0;\r\n\tvar expired = 0;\r\n\tvar fileSmartpay = \"C:\\\\SmartPay App\\\\transaction.json\";\r\n\tvar transact = file.For(fileSmartpay).CreateFolder().Read();\r\n\t\r\n\tif (transact != \"[]\" || transact != \"\")\r\n\t{\r\n\t\tvar jsonObject = JSON.parse(transact);\r\n\t\tvar orderid = jsonObject.order;\r\n\t\tvar refund_ = jsonObject.refund;\r\n\t\ttransact = jsonObject.amount;\r\n\t\t\r\n\t\tif (orderid != order)\r\n\t\t{\r\n\t\t\ttransact = \"0\";\r\n\t\t}\t\r\n\t}\r\n\telse\r\n\t{\r\n\t\ttransact = \"0\";\r\n\t}\r\n\t\r\n\tData.Set('SmartPay', Helper.ToNumber(transact));\r\n\treturn Data.Get('SmartPay'); //zHelper.ToNumber(transact);\r\n}\r\n\r\n\r\nfunction ClearTransact()\r\n{\r\n\tvar fileSmartpay = \"C:\\\\SmartPay App\\\\transaction-smartpay.json\";\r\n\tfile.For(fileSmartpay).CreateFolder().Write(\"\");\r\n\t\r\n\treturn false;\r\n}\r\n\r\n\r\nfunction Sleep(delay_)\r\n{\r\n\tvar startDate = dt.Day(0);\r\n\tvar good = true;\r\n\tvar date_ = new Date();\r\n\tvar startSecs_ = date_.getSeconds();\r\n\tvar endSecs_ = 0;\r\n\twhile (good)\r\n\t{\r\n\t\t\r\n\t\tvar endDate_ = new Date();\r\n\t\tendSecs_ = endDate_.getSeconds();\t\t\r\n\t\t\r\n\t\tif ((endSecs_ - startSecs_) >= delay_)\r\n\t\t\tgood = false;\r\n\t}\r\n\treturn delay_;\r\n}\r\n\r\nfunction CheckTransact(duration_)\r\n{\r\n\tvar lib = host.lib(\"mscorlib\");\r\n\tData.Set('SmartPay', \"0\");\r\n\t\r\n\tvar delay_ = duration_;\r\n\tdelay_ = 100;\r\n\t\r\n\tvar good = true;\t\r\n\tvar fileSmartpay = \"C:\\\\SmartPay App\\\\transaction-smartpay.json\";\r\n\tvar transact = 0;\r\n\tvar refund = 0;\r\n\t\r\n\tvar startDate_ = new Date();\r\n\t\r\n\tvar cnt = 0;\r\n\tvar fee = 0;\r\n\tvar orderid = \"\";\r\n\tvar boolRead = false;\r\n\t\r\n\t\r\n\twhile (good)\r\n\t{\r\n\t\tvar content_ = \"\";\r\n\t\t//try {\r\n\t\t    // Attempt the file read block\r\n\t\t    content_ = file.For(fileSmartpay).CreateFolder().Read();\r\n\t\t//} catch (err) {\r\n\t\t    // If the file is locked by the payment app writing to it, \r\n\t\t    // catch the error and let the loop try again safely on the next cycle pass.\r\n\t\t//    content_ = \"\"; \r\n\t\t//}\r\n\r\n\t\t\r\n\t\tif (content_ != \"\")\r\n\t\t{\r\n\t\t\ttry\r\n\t\t\t{\r\n\t\t\t\tvar jsonObject = JSON.parse(content_);\r\n\t\t\t\tvar orderid = jsonObject.order;\r\n\t\t\t\trefund = jsonObject.refund;\r\n\t\t\t\ttransact = jsonObject.amount;\r\n\t\t\t\tfee = jsonObject.fee;\r\n\t\t\t\t//return transact;\r\n\t\t\t\t\r\n\t\t\t} catch (ess) {\r\n\t\t\t\t//return content; //ess.Message;\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar endDate_ = new Date();\r\n\t\t\r\n\t\tvar distance_ = Math.abs(endDate_.getTime() - startDate_.getTime()) / 1000;\r\n\t\t\r\n\t\tif ((distance_ > duration_) )\r\n\t\t{\r\n\r\n\t\t\tData.Set('SmartPay', transact);\r\n\t\t\tData.Set('SmartPayFee', fee);\r\n\t\t\treturn Data.Get('SmartPay');\r\n\t\t}\r\n\t\t\r\n\t\tif (!isRunning(\"SambaPayment.exe\"))\r\n\t\t{\r\n\t\t\tData.Set('SmartPay', transact);\r\n\t\t\tData.Set('SmartPayFee', fee);\r\n\t\t\treturn Data.Get('SmartPay');\r\n\t\t}\r\n \t\t\r\n\t\t//if ((endSecs_ - startSecs_) >= delay_)\r\n\t\t//\tgood = false;\r\n\t\t\r\n\t\tcnt++;\r\n\t\t\r\n\t\tif (cnt % 20 == 0)\r\n\t\t{\r\n\t\t\tlib.System.Threading.Thread.Sleep(3);\r\n\t\t}\r\n\t\t//Sleep(1);\r\n\t\t\r\n\t\t//return 20;\r\n\t}\r\n\r\n\tData.Set('SmartPay', transact);\r\n\tData.Set('SmartPayFee', fee);\r\n\r\n\treturn 20;//Data.Get('SmartPay');\r\n}\r\n\r\nfunction GetData(DataName)\r\n{\r\n\treturn Helper.ToNumber(Data.Get(DataName));\r\n}\r\n\r\n\r\nfunction ConfirmTransact()\r\n{\r\n\tvar fileSmartpay = \"C:\\\\SmartPay App\\\\transaction-smartpay.json\";\r\n\tvar content_ = file.For(fileSmartpay).CreateFolder().Read();\r\n\t\r\n\tif (content_ == \"\")\r\n\t{\r\n\t\tcontent_ = \"{\\\"order\\\":\\\"2123\\\",\\\"amount\\\":\\\"0.00\\\",\\\"status\\\":\\\"true\\\",\\\"unique\\\":\\\"GBPOS\\\",\\\"refund\\\":false, \\\"fee\\\": 0}\";\t\r\n\t\tfile.For(fileSmartpay).CreateFolder().Write(content_);\r\n\t}\r\n\t\r\n\treturn true;\r\n}\r\n\r\nfunction AddFees(id, services)\r\n{\r\n\tvar fileSmartpay = \"C:\\\\SmartPay App\\\\transaction-fees.json\";\r\n\t//var content_ = \"{\\\"ticket\\\":\\\"\" + id + \"\\\",\\\"amount\\\":\\\"\" + amount + \"\\\"}\";\t\r\n\r\n\tvar content_ = \"\";\r\n\t\r\n\tfile.For(fileSmartpay).CreateFolder().Write(content_);\r\n\r\n\treturn services;\r\n}\r\n\r\nfunction isRunning(processName) {\r\n  var host = \".\";\r\n  var wmi = GetObject(\"winmgmts:{impersonationLevel=impersonate}!\\\\\\\\\" + host + \"\\\\root\\\\cimv2\");\r\n  \r\n  // Query the system for the specific process name\r\n  var processes = wmi.ExecQuery(\"SELECT * FROM Win32_Process WHERE Name = '\" + processName + \"'\");\r\n  \r\n  // If the collection count is greater than 0, the process is running\r\n  if (processes.Count > 0) {\r\n    return true;\r\n  }\r\n  return false;\r\n}\n\n// Purchase-only test patch on v1.3. Refund functions and ticket-save timing stay unchanged.\nfunction PrepareFastPurchase(order) {\n    Data.Set(\"SmartPay\", 0);\n    Data.Set(\"SmartPayFee\", 0);\n    Data.Set(\"FastPayReady\", 0);\n    Data.Set(\"FastPayApproved\", 0);\n    Data.Set(\"FastPayError\", \"\");\n    Data.Set(\"FastManualPending\", 0);\n    Data.Set(\"FastManualApproved\", 0);\n    Data.Set(\"FastPayRequest\", \"\");\n    // Keep unsaved ticket 0 supported; do not save/submit orders to obtain an ID.\n    if (!/^\\d+$/.test(String(order))) return FastPayFail(\"SmartPay: invalid ticket identifier.\");\n    try {\n        file.For(\"C:\\\\SmartPay App\\\\transaction-smartpay.json\").CreateFolder().Write(\"\");\n        file.For(\"C:\\\\SmartPay App\\\\purchase-started.json\").CreateFolder().Write(\"\");\n        Data.Set(\"FastPayOrder\", String(order));\n        Data.Set(\"FastPayRequest\", \"GBPOS\" + host.lib(\"mscorlib\").System.Guid.NewGuid().ToString(\"N\"));\n        Data.Set(\"FastPayReady\", 1);\n        return true;\n    } catch (error) {\n        return FastPayFail(\"SmartPay preparation failed. Check file permissions and running processes.\");\n    }\n}\nfunction AcquireFastPurchase(order) {\n    Data.Set(\"FastPayDuplicateNotice\", 0);\n    if (Number(Data.Get(\"FastManualPending\")) === 1) {\n        Data.Set(\"FastPayError\", \"A SmartPay transaction is already in progress. Check the terminal and wait.\");\n        Data.Set(\"FastPayDuplicateNotice\", 1);\n        return 0;\n    }\n    try {\n        var system = host.lib(\"mscorlib\").System;\n        var domain = system.AppDomain.CurrentDomain;\n        if (domain.GetData(\"GBPOS.FastPay.LockHandle\") != null) {\n            Data.Set(\"FastPayError\", \"A SmartPay transaction is already in progress. Check the terminal and wait.\");\n            Data.Set(\"FastPayDuplicateNotice\", 1);\n            return 0;\n        }\n        if (isRunning(\"SambaPayment.exe\")) {\n            Data.Set(\"FastPayError\", \"SmartPay is already open. Check that transaction before retrying.\");\n            Data.Set(\"FastPayDuplicateNotice\", 1);\n            return 0;\n        }\n        // FileShare.None makes acquisition atomic across simultaneous SambaPOS\n        // rule threads and across separate SambaPOS processes on this machine.\n        var handle = system.IO.File.Open(\n            \"C:\\\\SmartPay App\\\\smartpay-integration.lock\",\n            system.IO.FileMode.OpenOrCreate,\n            system.IO.FileAccess.ReadWrite,\n            system.IO.FileShare.None);\n        domain.SetData(\"GBPOS.FastPay.LockHandle\", handle);\n    } catch (runningError) {\n        Data.Set(\"FastPayError\", \"Another SmartPay transaction may be in progress. Check the terminal and wait.\");\n        Data.Set(\"FastPayDuplicateNotice\", 1);\n        return 0;\n    }\n    Data.Set(\"FastPayInProgress\", 1);\n    Data.Set(\"FastPayReservedOrder\", String(order));\n    return 1;\n}\nfunction ReleaseFastPayLock() {\n    try {\n        var system = host.lib(\"mscorlib\").System;\n        var domain = system.AppDomain.CurrentDomain;\n        var handle = domain.GetData(\"GBPOS.FastPay.LockHandle\");\n        domain.SetData(\"GBPOS.FastPay.LockHandle\", null);\n        if (handle != null) handle.Close();\n    } catch (ignored) { }\n    Data.Set(\"FastPayInProgress\", 0);\n}\nfunction ClearFastPayNotice() {\n    Data.Set(\"FastPayDuplicateNotice\", 0);\n    Data.Set(\"FastPayError\", \"\");\n    return true;\n}\nfunction FastPayFail(message) {\n    Data.Set(\"SmartPay\", 0);\n    Data.Set(\"SmartPayFee\", 0);\n    Data.Set(\"FastPayReady\", 0);\n    Data.Set(\"FastPayApproved\", 0);\n    Data.Set(\"FastManualPending\", 0);\n    Data.Set(\"FastManualApproved\", 0);\n    ReleaseFastPayLock();\n    Data.Set(\"FastPayError\", message);\n    return 0;\n}\nfunction FastPayMoney(value, fee) {\n    if (typeof value !== \"number\" && typeof value !== \"string\") return null;\n    var text = String(value);\n    var pattern = fee ? /^\\d+(?:\\.\\d+)?$/ : /^(?:\\d+|\\d{1,3}(?:,\\d{3})+)(?:\\.\\d{1,2})?$/;\n    if (!pattern.test(text)) return null;\n    var n = Number(text.replace(/,/g, \"\"));\n    if (!isFinite(n) || n < 0) return null;\n    var rounded = Math.round(n * 100) / 100;\n    if (!isFinite(rounded) || Math.abs(n - rounded) > 0.0000001) return null;\n    return rounded;\n}\nfunction ReadFastPurchase() {\n    try {\n        var text = file.For(\"C:\\\\SmartPay App\\\\transaction-smartpay.json\").CreateFolder().Read();\n        if (!text) return null;\n        var result = JSON.parse(text);\n        if (!result || String(result.order) !== String(Data.Get(\"FastPayOrder\")) ||\n            String(result.unique) !== String(Data.Get(\"FastPayRequest\"))) return null;\n        if (result.status === false || result.status === \"false\") return {failed:true};\n        if (result.status !== true && result.status !== \"true\") return null;\n        if (result.refund !== false && result.refund !== \"false\") return null;\n        var amount = FastPayMoney(result.amount, false), fee = FastPayMoney(result.fee, true);\n        if (amount === null || amount <= 0 || fee === null || fee > amount) return null;\n        return {amount:amount, fee:fee};\n    } catch (error) {\n        return null; // Retry partial writes and sharing violations, without accepting a partial result.\n    }\n}\nfunction ReadFastPurchaseStart() {\n    try {\n        var text = file.For(\"C:\\\\SmartPay App\\\\purchase-started.json\").CreateFolder().Read();\n        if (!text) return false;\n        var started = JSON.parse(text);\n        return started && String(started.order) === String(Data.Get(\"FastPayOrder\")) &&\n            String(started.unique) === String(Data.Get(\"FastPayRequest\"));\n    } catch (error) {\n        return false;\n    }\n}\nfunction AcceptFastPurchaseResult(result) {\n    Data.Set(\"SmartPay\", result.amount);\n    Data.Set(\"SmartPayFee\", result.fee);\n    Data.Set(\"FastPayReady\", 0);\n    Data.Set(\"FastPayApproved\", 1);\n    Data.Set(\"FastManualPending\", 0);\n    return result.amount;\n}\nfunction CheckFastPurchaseFromStart(duration, baseAmount) {\n    if (Number(Data.Get(\"FastPayReady\")) !== 1) return 0;\n    var lib = host.lib(\"mscorlib\");\n    while (true) {\n        var early = ReadFastPurchase();\n        if (early && early.failed)\n            return FastPayFail(\"Transaction was cancelled before Purchase started.\");\n        if (early) return AcceptFastPurchaseResult(early);\n        if (ReadFastPurchaseStart()) return CheckFastPurchase(duration, baseAmount);\n        lib.System.Threading.Thread.Sleep(100);\n    }\n}\nfunction CheckFastPurchase(duration, baseAmount) {\n    if (Number(Data.Get(\"FastPayReady\")) !== 1) return 0;\n    var limit = Number(duration);\n    if (!isFinite(limit) || limit < 1 || limit > 300) limit = 130;\n    var lib = host.lib(\"mscorlib\"), start = new Date().getTime();\n    while (new Date().getTime() - start < limit * 1000) {\n        var result = ReadFastPurchase();\n        if (result && result.failed)\n            return FastPayFail(\"Transaction reported an unsuccessful result. No payment was recorded in SambaPOS.\");\n        if (result) {\n            AcceptFastPurchaseResult(result);\n            // Do not wait for process exit: the app writes its final result before closing.\n            return result.amount;\n        }\n        lib.System.Threading.Thread.Sleep(100);\n    }\n    var base = FastPayMoney(baseAmount, false);\n    Data.Set(\"SmartPay\", 0);\n    Data.Set(\"SmartPayFee\", 0);\n    Data.Set(\"FastPayReady\", 0);\n    Data.Set(\"FastPayApproved\", 0);\n    Data.Set(\"FastPayError\", \"\");\n    Data.Set(\"FastManualApproved\", 0);\n    Data.Set(\"FastManualBase\", base === null || base <= 0 ? 0 : base);\n    // Even if the base amount is unusable, keep a visible manual/cancel path.\n    // Credit/Debit remains fail-closed; Cancel releases only after terminal check.\n    Data.Set(\"FastManualPending\", 1);\n    return 0;\n}\nfunction FastPurchaseReady(order) {\n    return String(order) === String(Data.Get(\"FastPayOrder\")) &&\n        Number(Data.Get(\"FastPayApproved\")) === 1 ? 1 : 0;\n}\nfunction ClaimFastPurchase(order) {\n    if (FastPurchaseReady(order) !== 1) {\n        Data.Set(\"SmartPay\", 0);\n        Data.Set(\"SmartPayFee\", 0);\n        return false;\n    }\n    Data.Set(\"FastPayApproved\", 0); // No automatic replay of accounting after this point.\n    return true;\n}\nfunction CompleteFastPurchase() {\n    // Called only after fee, payment processing and Save Ticket have completed.\n    ReleaseFastPayLock();\n    Data.Set(\"FastPayDuplicateNotice\", 0);\n    Data.Set(\"FastPayApproved\", 0);\n    Data.Set(\"FastManualApproved\", 0);\n    return true;\n}\nfunction ReadConfiguredCreditFeePercent() {\n    try {\n        var shell = new ActiveXObject(\"WScript.Shell\");\n        var raw = shell.RegRead(\"HKLM\\\\SOFTWARE\\\\SmartPay App\\\\Configuration\\\\Credit Card Fee (%)\");\n        var text = String(raw).replace(/^\\s+|\\s+$/g, \"\");\n        if (!/^\\d+(?:[\\.,]\\d+)?$/.test(text)) return null;\n        var value = Number(text.replace(\",\", \".\"));\n        return isFinite(value) && value >= 0 && value <= 100 ? value : null;\n    } catch (error) {\n        try {\n            // Covers installations where a 32/64-bit registry view differs.\n            var shell64 = new ActiveXObject(\"WScript.Shell\");\n            var raw64 = shell64.RegRead(\"HKLM\\\\SOFTWARE\\\\WOW6432Node\\\\SmartPay App\\\\Configuration\\\\Credit Card Fee (%)\");\n            var text64 = String(raw64).replace(/^\\s+|\\s+$/g, \"\");\n            if (!/^\\d+(?:[\\.,]\\d+)?$/.test(text64)) return null;\n            var value64 = Number(text64.replace(\",\", \".\"));\n            return isFinite(value64) && value64 >= 0 && value64 <= 100 ? value64 : null;\n        } catch (ignored) {\n            return null;\n        }\n    }\n}\nfunction PrepareManualPurchase(order, cardType) {\n    Data.Set(\"SmartPay\", 0);\n    Data.Set(\"SmartPayFee\", 0);\n    Data.Set(\"FastManualApproved\", 0);\n    if (Number(Data.Get(\"FastManualPending\")) !== 1 ||\n        String(order) !== String(Data.Get(\"FastPayOrder\"))) return false;\n    var base = FastPayMoney(Data.Get(\"FastManualBase\"), false);\n    if (base === null || base <= 0) return false;\n    var fee = 0;\n    if (cardType === \"Credit\") {\n        var percent = ReadConfiguredCreditFeePercent();\n        if (percent === null) {\n            Data.Set(\"FastPayError\", \"Credit Card Fee setting could not be read.\");\n            return false;\n        }\n        fee = Math.round(base * percent) / 100;\n    } else if (cardType !== \"Debit\") {\n        return false;\n    }\n    Data.Set(\"SmartPayFee\", fee);\n    Data.Set(\"SmartPay\", Math.round((base + fee) * 100) / 100);\n    Data.Set(\"FastManualPending\", 0);\n    Data.Set(\"FastManualApproved\", 1);\n    return true;\n}\nfunction CancelManualPurchase() {\n    Data.Set(\"SmartPay\", 0);\n    Data.Set(\"SmartPayFee\", 0);\n    Data.Set(\"FastManualPending\", 0);\n    Data.Set(\"FastManualApproved\", 0);\n    ReleaseFastPayLock();\n    Data.Set(\"FastPayError\", \"\");\n    return true;\n}","HandlerName":"Payment","Name":"SCR-SmartPayFunction"}],"States":[{"Color":null,"DisplayFormat":null,"GroupName":"GStatus","Name":"Gift","PriceFormat":null,"QuantityFormat":null,"ShowOnEndOfDayReport":true,"ShowOnProductReport":true,"ShowOnTicket":true,"StateType":2}],"TaskTypes":null,"TicketTagGroups":null,"TicketTypes":null,"Triggers":null}